﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Xml;
using CAION2.Classes;
using CAION2.Commands;
using CAION2.Models;
using CAION2.Properties;
using CAION2.Views;
using FirstFloor.ModernUI.Windows.Controls;

namespace CAION2.ViewModels
{
    class RrViewModel : ViewModelBase
    {

        #region Vars

        private CraftProfession _selectedProfession;
        private ObservableCollection<CraftProfession> _craftProfessions;
        private ObservableCollection<Recipe> _recipesList;
        private Recipe _selectedRecipe;
        private ItemCardViewModel _card1DataContext;
        private ItemCardViewModel _card2DataContext;
        private string _filterText;
        private ICollectionView _recipesListView;

        private string _recipesListCount;
        private Thickness _filterErrorBorder;
        private Visibility _pageContentVisible = Visibility.Hidden;
        private Visibility _loadBarVisible = Visibility.Hidden;

        #endregion

        #region Properties

        public ObservableCollection<CraftProfession> CraftProfessions
        {
            get { return _craftProfessions; }

            set
            {
                if (_craftProfessions == value) return;

                _craftProfessions = value;
                OnPropertyChanged("CraftProfessions");
            }
        }

        public CraftProfession SelectedProfession
        {
            get { return _selectedProfession; }

            set
            {
                if (_selectedProfession == value) return;

                _selectedProfession = value;
                OnPropertyChanged("SelectedProfession");
                LoadRecipesList();

                ClassConfiguration.SetValue("CraftProfession", CraftProfessions.IndexOf(SelectedProfession));

                if (PageContentVisible != Visibility.Visible) PageContentVisible = Visibility.Visible;

            }
        }

        private ObservableCollection<Recipe> RecipesList
        {
            get { return _recipesList; }

            set
            {
                if (_recipesList == value) return;

                _recipesList = value;
                OnPropertyChanged("RecipesList");
            }
        }

        public Recipe SelectedRecipe
        {
            get { return _selectedRecipe; }

            set
            {
                if (_selectedRecipe == value) return;

                _selectedRecipe = value;
                OnPropertyChanged("SelectedRecipe");
                
                if (_selectedRecipe == null) return;

                ObservableCollection<DataRow> rows = FillProductsTable();
                if (rows.Count == 0) return;

                Card1DataContext.IsCraftItem = true;
                Card1DataContext.LoadItemIndex = 0;
                Card1DataContext.Item = rows[0];
                Card1DataContext.LoadCard();

                if (rows.Count <= 1)
                {
                    return;
                }

                Card2DataContext.IsCraftItem = true;
                Card2DataContext.LoadItemIndex = 1;
                Card2DataContext.Item = rows[1];
                if (rows.Count > 2) Card2DataContext.SaveItem2 = rows[2];
                Card2DataContext.LoadCard();
            }
        }

        public ItemCardViewModel Card1DataContext
        {
            get { return _card1DataContext; }

            set
            {
                if (_card1DataContext == value) return;

                _card1DataContext = value;
                OnPropertyChanged("Card1DataContext");
            }
        }

        public ItemCardViewModel Card2DataContext
        {
            get { return _card2DataContext; }

            set
            {
                if (_card2DataContext == value) return;

                _card2DataContext = value;
                OnPropertyChanged("Card2DataContext");
            }
        }
        
        public string FilterText
        {
            get { return _filterText; }
            set
            {
                if (_filterText == value) return;

                _filterText = value;
                OnPropertyChanged("FilterText");

                RefreshRecipesListView();
            }
        }

        public ICollectionView RecipesListView
        {
            get { return _recipesListView; }
            set
            {
                if (_recipesListView == value) return;

                _recipesListView = value;
                OnPropertyChanged("RecipesListView");
            }
        }

        public string RecipesListCount
        {
            get { return _recipesListCount; }
            set
            {
                if (_recipesListCount == value) return;

                _recipesListCount = value;
                OnPropertyChanged("RecipesListCount");
            }
        }

        public Thickness FilterErrorBorder
        {
            get { return _filterErrorBorder; }
            set
            {
                if (_filterErrorBorder == value) return;

                _filterErrorBorder = value;
                OnPropertyChanged("FilterErrorBorder");
            }
        }
        

        public Visibility PageContentVisible
        {
            get { return _pageContentVisible; }
            set
            {
                if (_pageContentVisible == value) return;

                _pageContentVisible = value;
                OnPropertyChanged("PageContentVisible");
            }
        }

        public Visibility LoadBarVisible
        {
            get { return _loadBarVisible; }
            set
            {
                if (_loadBarVisible == value) return;

                _loadBarVisible = value;
                OnPropertyChanged("LoadBarVisible");
            }
        }
        

        #endregion
        

        #region Vars Recepture

        private ObservableCollection<ReceptureNode> _receptureTree;

        #endregion

        #region Properties Recepture

        public ObservableCollection<ReceptureNode> ReceptureTree
        {
            get { return _receptureTree; }
            set
            {
                _receptureTree = value;
                OnPropertyChanged("ReceptureTree");
            }
        }

        #endregion


        #region Commands

        public RelayCommand<DataRow> SelectRecipeForReceptureCommand { get; private set; }
        public RelayCommand OpenExtendedFilterCommand { get; private set; }

        #endregion


        public RrViewModel()
        {
            WireCommands();
            FillListOfCraftProfessions();
            
            Card1DataContext = new ItemCardViewModel();
            Card2DataContext = new ItemCardViewModel();
            //PageContentVisible = Visibility.Hidden;

            RecipesList = new ObservableCollection<Recipe>();
            RecipesListView = CollectionViewSource.GetDefaultView(_recipesList);
            RecipesListView.Filter = ApplyFilter;

            SelectedProfession = CraftProfessions[Convert.ToInt32(ClassConfiguration.GetValue("CraftProfession"))];
        }

        private void WireCommands()
        {
            SelectRecipeForReceptureCommand = new RelayCommand<DataRow>(SelectRecipeForRecepture) { IsEnabled = true };
            OpenExtendedFilterCommand = new RelayCommand(OpenExtendedFilter) { IsEnabled = true };

        }

        private void FillListOfCraftProfessions()
        {
            CraftProfessions = new ObservableCollection<CraftProfession>
                {
                    new CraftProfession("convert", Resources.RR_Profession2, "Recipes_Convert"),
                    new CraftProfession("armorsmith", Resources.RR_Profession1, "Recipes_Armorsmith"),
                    new CraftProfession("cooking", Resources.RR_Profession3, "Recipes_Cooking"),
                    new CraftProfession("handiwork", Resources.RR_Profession4, "Recipes_Handiwork"),
                    new CraftProfession("tailoring", Resources.RR_Profession5, "Recipes_Tailoring"),
                    new CraftProfession("weaponsmith", Resources.RR_Profession6, "Recipes_Weaponsmith"),
                    new CraftProfession("alchemy", Resources.RR_Profession7, "Recipes_Alchemy"),
                    new CraftProfession("menuisier", Resources.RR_Profession8, "Recipes_Menuisier")
                };
            OnPropertyChanged("CraftProfessions");
        }

        private void LoadRecipesList()
        {
            //LoadBarVisible = Visibility.Visible;

            RecipesList = DataModel.GetRecipesList(SelectedProfession.DataTableName);
            RecipesListView = CollectionViewSource.GetDefaultView(_recipesList);
            RecipesListView.Filter = ApplyFilter;
            SetFilter();
            
            //LoadBarVisible = Visibility.Hidden;
        }
        
        private void OpenExtendedFilter()
        {
            new ModernDialog
                {
                    Content = new ExtendedFilterForRecipesPage(),
                    WindowStartupLocation = WindowStartupLocation.CenterScreen,
                    Title = Resources.RR_FilterEx
                }.ShowDialog();

            RefreshRecipesListView();
        }

        private void SetFilter()
        {
            int recipesCount = _recipesListView.Cast<object>().Count();
            RecipesListCount = String.Format(Resources.RR_FindRecipes, recipesCount);
            
            if (FilterText != null)
            {
                FilterErrorBorder = recipesCount == 0 ? new Thickness(1) : new Thickness(0);
            }
        }

        private bool ApplyFilter(object o)
        {
            if (o == null) {return true;}
            Recipe item = o as Recipe;
            
            bool textFlag = false;
            if (String.IsNullOrEmpty(FilterText))
            {
                textFlag = true;
            }
            else
            {
                if (item != null && (item.Translate.IndexOf(FilterText, StringComparison.OrdinalIgnoreCase) >= 0
                                     || item.Translate2.IndexOf(FilterText, StringComparison.OrdinalIgnoreCase) >= 0))
                {
                    textFlag = true;
                }
            }

            return textFlag;
        }

        private void RefreshRecipesListView()
        {
            if (RecipesList == null) return;

            LoadRecipesList();

            RecipesListView.Refresh();
            SetFilter();
        }

        private ObservableCollection<DataRow> FillProductsTable()
        {
            string pList = string.Format("('{0}',", _selectedRecipe.Product);

            if (!String.IsNullOrEmpty(_selectedRecipe.Combo1))
                pList += string.Format("'{0}',", _selectedRecipe.Combo1);
            if (!String.IsNullOrEmpty(_selectedRecipe.Combo2))
                pList += string.Format("'{0}',", _selectedRecipe.Combo2);
            if (!String.IsNullOrEmpty(_selectedRecipe.Combo3))
                pList += string.Format("'{0}',", _selectedRecipe.Combo3);
            if (!String.IsNullOrEmpty(_selectedRecipe.Combo4))
                pList += string.Format("'{0}'", _selectedRecipe.Combo4);

            if (pList.EndsWith(",")) pList = pList.Substring(0, pList.Length - 1);
            pList += ")";
            pList = string.Format("name IN {0}", pList);

            DataTable table = DataModel.GetTable("ProductsForRecipes", "*", pList);
            ObservableCollection<DataRow> result = new ObservableCollection<DataRow>();
            foreach (DataRow row in table.Rows)
            {
                result.Add(row);
            }
            
            return result;
        }
        
        private void SelectRecipeForRecepture(DataRow row)
        {
            
        }
    }

    class ReceptureNode : ViewModelBase
    {
        private bool _expanded;
        private bool _selected;

        public string NameComponent { get; set; }
        public ObservableCollection<ReceptureNode> Children { get; set; }
        public XmlNode ComponentNode { get; set; }

        public bool Expanded
        {
            get { return _expanded; }

            set
            {
                _expanded = value;
                OnPropertyChanged("Expanded");
                UpdateXmlExpanded();
            }
        }

        public bool Selected
        {
            get { return _selected; }
            set
            {
                _selected = value;
                OnPropertyChanged("Selected");
                UpdateXmlSelected();
            }
        }

        public Int16 RecipeCount { get; set; }
        public string Icon { get; set; }
        public string ItemType { get; set; }
        public Visibility Critical { get; set; }
        public Int16 RecipeLevel { get; set; }
        public Int16 ProductCount { get; set; }
        public Int16 Dp { get; set; }
        public Int32 FullCount { get; set; }
        public bool First { get; set; }
        public string PurchaseText { get; set; }
        public Int32 CraftCount { get; set; }

        private void UpdateXmlExpanded()
        {
            if (ComponentNode == null || ComponentNode.Attributes == null) return;
            XmlAttribute xExpanded = ComponentNode.Attributes["expanded"];
            if (xExpanded != null) xExpanded.Value = Expanded.ToString();
        }

        private void UpdateXmlSelected()
        {
            if (ComponentNode == null || ComponentNode.Attributes == null) return;
            XmlAttribute xSelected = ComponentNode.Attributes["selected"];
            if (xSelected != null) xSelected.Value = Selected.ToString();
        }
    }
    
}
